iT邦幫忙

2023 iThome 鐵人賽

DAY 17
0
Software Development

Should I use fp-ts系列 第 17

[Should I use fp-ts?] Day 17 - fp-ts: Option

  • 分享至 

  • xImage
  •  

在本系列文中,所有的程式碼以及測試都可以在 should-i-use-fp-ts 找到,今日的範例放在 src/day-17 並且有習題和測試可以讓大家練習。

validation

今天我們來看看平常寫業務邏輯的時候比較常使用 Option 的部分。
使用 Option 的情境通常會滿足兩項條件。

  1. 有失敗的預設值。
  2. 不在乎是哪邊失敗。
    日常使用中比較適合的情境為 validation,先來看非 Option 實作,這個情境為 user 的 validate,需滿足所有條件才會回傳 user
type User = {
  username: string;
  email: string;
  password: string;
};

const moreThan3Chars = (xs: string): string | null => 
    xs.length > 3 ? xs : null;
const validateEmail = (email: string): string | null => 
    email.includes('@') ? email : null;
const moreThan6Chars = (xs: string): string | null => 
    xs.length > 6 ? xs : null;
const hasCapital = (xs: string): string | null => 
    /[A-Z]/.test(xs) ? xs : null;
const hasNumber = (xs: string): string | null => 
    /\d/.test(xs) ? xs : null;

const validateOriginal = (user: User) => {
  if (!moreThan3Chars(user.username)) return null;

  if (!validateEmail(user.email)) return null;

  if (!moreThan6Chars(user.password)) return null;
  if (!hasCapital(user.password)) return null;
  if (!hasNumber(user.password)) return null;

  return { username: user.username, email: user.email, password: user.password };
};

接下來展示 Option 的實作。

const moreThan3CharsOption = O.fromPredicate((xs: string) => 
    xs.length > 3);
const validateEmailOption = O.fromPredicate((xs: string) => 
    xs.includes('@'));
const moreThan6CharsOption = O.fromPredicate((xs: string) => 
    xs.length > 6);
const hasCapitalOption = O.fromPredicate((xs: string) => 
    /[A-Z]/.test(xs));
const hasNumberOption = O.fromPredicate((xs: string) => 
    /\d/.test(xs));

export const validateOption = ({ username, email, password }: User) => pipe(
  username,
  moreThan3CharsOption,
  O.bindTo('username'),
  O.bind('email', () => validateEmailOption(email)),
  O.bind('password', () => pipe(
    password,
    moreThan6CharsOption,
    O.chain(hasCapitalOption),
    O.chain(hasNumberOption),
  )),
  O.getOrElseW(() => null),
);

大家會比較喜歡哪種形式呢?
再來,或許有人會說:"沒有客製化錯誤訊息我怎麼知道錯在哪裡?"。沒關係,等明天開始學習 Either,我們就可以針對失敗的情境添加訊息。

今天的主題在 should-i-use-fp-ts src/day-17 有習題和測試可以練習,大家可以嘗試自己能不能寫出自己的 validate。

Reference

Option.ts | fp-ts


上一篇
[Should I use fp-ts?] Day 16 - fp-ts: Option apS
下一篇
[Should I use fp-ts?] Day 18 - fp-ts Either type and constructor
系列文
Should I use fp-ts25
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言